package com.xiaoyu.lanling.feature.voicematch

import `in`.srain.cube.util.CLog
import `in`.srain.cube.util.LocalDisplay
import `in`.srain.cube.util.TimeUtils
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.SystemClock
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.imuxuan.floatingview.FloatingMagnetView
import com.imuxuan.floatingview.FloatingView
import com.imuxuan.floatingview.MagnetViewListener
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.app.GlobalUI
import com.xiaoyu.base.model.User
import com.xiaoyu.base.utils.RxUtils
import com.xiaoyu.base.utils.extensions.dp
import com.xiaoyu.base.utils.extensions.setOnClickDebounceListener
import com.xiaoyu.base.utils.time.CountDown
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.media.image.ImageViewUtil
import com.xiaoyu.lanling.view.UserAvatarDraweeView
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit

class VoiceCallFloatWindowManager {

    private val viewHolderMap = mutableMapOf<String, MutableMap<String, ViewHolder>>()
    private val typeFloatView = "view"
    private val typeFloatWindow = "window"

    private var mTimerDisposable: Disposable? = null

    private class ViewHolder(val floatView: View, val timeView: TextView, val draweeView: UserAvatarDraweeView)

    private fun inflateFloatView(activity: Activity, type: String): View {
        val layoutInflater = LayoutInflater.from(AppContext.getContext())
        val floatView = layoutInflater.inflate(R.layout.voice_match_float_window_view, null, false)
        floatView.let {
            val draweeView: UserAvatarDraweeView = it.findViewById(R.id.voice_match_float_window_drawee_view)
            val statusView: TextView = it.findViewById(R.id.voice_match_float_window_status)

            val typeMap = mutableMapOf<String, ViewHolder>()
            typeMap[type] = ViewHolder(floatView, statusView, draweeView)
            viewHolderMap.put(activity.javaClass.simpleName, typeMap)
        }
        return floatView
    }

    fun showFloatWindow(activity: Activity, startMs: Long, needShow: Boolean, user: User?) {
        RxUtils.disposable(mTimerDisposable)

        if (needShow) {
            showFloatWindow(activity)

            val isShowStatus = startMs == -1L
            getFloatViewHolder(activity, false)?.let { viewHolder ->
                user?.let { it ->
                    ImageViewUtil.loadAvatarRound(viewHolder.draweeView, it, 40)
                }

                if (!isShowStatus) {
                    createCountdownTimer(activity, false, startMs)
                }
            }
        }
    }

    fun hideAndStopFloatWindow() {
        RxUtils.disposable(mTimerDisposable)
        FloatingView.get().remove()
    }

    fun destroyFloatWindow(activity: Activity) {
        FloatingView.get().remove()
    }

    private fun getFloatViewHolder(activity: Activity, hasPermission: Boolean): ViewHolder? {
        return viewHolderMap[getFloatWindowTag(activity)]?.get(if (hasPermission) typeFloatWindow else typeFloatView)
    }

    private fun createCountdownTimer(activity: Activity, hasPermission: Boolean, startMs: Long) {
        RxUtils.disposable(mTimerDisposable)
        mTimerDisposable = Observable.interval(0, 1000, TimeUnit.MILLISECONDS)
                .compose(RxUtils.ioToMainObservableScheduler())
                .subscribe {
                    val curMs = SystemClock.elapsedRealtime()
                    val durationS = (curMs - startMs) / 1000
                    val timeView = getFloatViewHolder(activity, hasPermission)?.timeView
                    if (durationS < TimeUtils.HOUR_MS) {
                        timeView?.text = TimeUtils.secondsToClockText(durationS)
                    } else {
                        timeView?.text = TimeUtils.secondsToDigitalText(durationS)
                    }
                }
    }

    private fun showFloatWindow(activity: Activity) {
        val floatView = inflateFloatView(activity, typeFloatView);

        val floatingMagnetView = FloatingMagnetView(AppContext.getContext())
        floatingMagnetView.layoutParams = ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        floatingMagnetView.x = LocalDisplay.SCREEN_WIDTH_PIXELS * 0.8F
        floatingMagnetView.y = LocalDisplay.SCREEN_HEIGHT_PIXELS * 0.3F
        floatingMagnetView.setMagnetViewListener(object : MagnetViewListener {
            override fun onClick(magnetView: FloatingMagnetView?) {
                val intent = Intent(AppContext.getContext(), activity.javaClass)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
                AppContext.getContext().startActivity(intent)
            }

            override fun onRemove(magnetView: FloatingMagnetView?) {
            }
        })
        floatingMagnetView.addView(floatView)

        FloatingView.get()
                .customView(floatingMagnetView)
                .show()
    }

    private fun getFloatWindowTag(activity: Activity): String {
        return activity.javaClass.simpleName
    }

    companion object {
        val TAG: String = VoiceCallFloatWindowManager::class.java.simpleName
        val instance by lazy { VoiceCallFloatWindowManager() }
    }
}